package problemSpace;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;

@XmlRootElement(name = "Order")
public class Order {

	@XmlElement(name = "OrderCode")
	public String orderCode;
	@XmlElement(name = "ConstructionYard")
	public ConstructionYard constructionYard;
	@XmlElement(name = "PumpLineLengthRequired")
	public String pumpLineLengthRequired;
	@XmlElement(name = "From")
	public Date from;
	@XmlElement(name = "TotalVolumeM3")
	public double totalVolumeM3;
	@XmlElement(name = "RequiredDischargeM3PerHour")
	public double requiredDischargeM3PerHour;
	@XmlElement(name = "PreferredStationCode")
	public String preferredStationCode;
	@XmlElementWrapper(name = "ProhibitedVehicleTypes")
	@XmlElement(name = "VehicleType")
	public ArrayList<String> prohibitedTypes;
	//DONTFIX: ipv String, VehicleType gebruiken
	//public VehicleType prohibitedType;
	@XmlElement(name = "MaximumVolumeAllowed")
	public boolean maximumVolumeAllowed;
	@XmlElement(name = "IsPickUp")
	public boolean isPickUp;
	@XmlTransient
	public boolean priority;
	@XmlTransient
	public int getPumpLineLengthRequiredM() {
		if(pumpLineLengthRequired.contains("."))
			return Integer.parseInt(pumpLineLengthRequired.substring(0,pumpLineLengthRequired.indexOf('.')));
		return Integer.parseInt(pumpLineLengthRequired.substring(0));
	}
	public void setPumpLineLengthRequiredM(String pumpLineLengthRequired) {
		this.pumpLineLengthRequired = pumpLineLengthRequired;
	}
	@XmlTransient
	public double remainingVolume;
	@XmlTransient
	public int failedTries;

	@XmlTransient
	public Date lastLoadingStop;

	public Order(){
		prohibitedTypes = new ArrayList<String>();
	}

	public Order(String orderCode, ConstructionYard constructionYard,
			double pumpLineLengthReq, Date fromDate, double totalVolumeM3,
			double requiredThroughput, String preferredStationCode,
			ArrayList<String> prohibitedType, boolean maxVolumeAllowed,
			boolean isPickUp, boolean priority) {
		this.orderCode = orderCode;
		this.constructionYard = constructionYard;
		this.pumpLineLengthRequired = Double.toString(pumpLineLengthReq);
		this.from = fromDate;
		this.totalVolumeM3 = totalVolumeM3;
		this.requiredDischargeM3PerHour = requiredThroughput;
		this.preferredStationCode = preferredStationCode;
		this.prohibitedTypes = prohibitedType;
		this.maximumVolumeAllowed = maxVolumeAllowed;
		this.isPickUp = isPickUp;
		this.priority = priority;
		this.remainingVolume = this.totalVolumeM3;
	}


	public Order(Order o) {
		this.orderCode = o.orderCode;
		this.constructionYard = o.constructionYard;
		this.pumpLineLengthRequired = o.pumpLineLengthRequired;
		this.from = o.from;
		this.totalVolumeM3 = o.totalVolumeM3;
		this.requiredDischargeM3PerHour = o.requiredDischargeM3PerHour;
		this.preferredStationCode = o.preferredStationCode;
		this.prohibitedTypes = o.prohibitedTypes;
		this.maximumVolumeAllowed = o.maximumVolumeAllowed;
		this.isPickUp = o.isPickUp;
		this.priority = o.priority;
		this.remainingVolume = o.remainingVolume;
	}
	public Delivery addVehicle(ArrayList<Vehicle> vehicleList, ArrayList<Station> stationList) {
		Collections.shuffle(vehicleList);
		Collections.shuffle(stationList);
		Vehicle v = vehicleList.get(0);
		Delivery d = new Delivery();
		for(Station s : stationList){
			if (v.preferedStationCode == null)
				v.preferedStationCode = s.stationCode;
			if(v.preferedStationCode.equals(s.stationCode)){
				if (this.remainingVolume > 0 && v.satisfies(this, s)) {
					d.departureStationCode = s.stationCode;
					d.returnStationCode = s.stationCode;
					// TODO mag hier het laatste element van v.occupied gebruikt worden? Waarschijnlijk wel aangezien net v.satisfies uitgevoerd maar check toch...
					d.loadingTime = v.occupied.get(v.occupied.size() - 1).getStart();
					// TODO check loadingTime (voor drivingMinutes) en unloadingTime (na dM) juist ingevuld
					d.unloadingTime = v.startUnloading;
					d.orderCode = this.orderCode;
					d.vehicleCode = v.vehicleCode;
					d.volume = v.volumeToDeliver;
					this.remainingVolume -= v.volumeToDeliver;
					if (this.lastLoadingStop == null)
						this.lastLoadingStop = this.from;
					this.from = v.lastUnloadingForOrder;
					this.failedTries = 0;
				} else
					this.failedTries++;
				break;
			}
		}
		if (d.orderCode == null)
			return null;
		else
			return d;
	}
	public void setRemainingVolume() {
		this.remainingVolume = this.totalVolumeM3;

	}
	public String toString(){
		return "orderNr: "+orderCode+", begin: "+from+", volume: "+totalVolumeM3 + ", remaining volume: " + remainingVolume;
	}
}
